namespace Peer.Web.Controls.Upload
{
    using System;
    using System.Collections;
    using System.IO;
    using System.Reflection;
    using System.Text;
    using System.Web;
    using System.Xml;

    internal class WebbHttpModule : IHttpModule
    {
        private DateTime m_beginTime = DateTime.Now;

        private byte[] AddTextPartToRequest(HttpWorkerRequest m_request, byte[] m_textData)
        {
            Type baseType;
            BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Instance;
            if (HttpContext.Current.Request.ServerVariables["SERVER_SOFTWARE"].Equals("Microsoft-IIS/6.0"))
            {
                baseType = m_request.GetType().BaseType.BaseType;
            }
            else
            {
                baseType = m_request.GetType().BaseType;
            }
            baseType.GetField("_contentAvailLength", bindingAttr).SetValue(m_request, m_textData.Length);
            baseType.GetField("_contentTotalLength", bindingAttr).SetValue(m_request, m_textData.Length);
            baseType.GetField("_preloadedContent", bindingAttr).SetValue(m_request, m_textData);
            baseType.GetField("_preloadedContentRead", bindingAttr).SetValue(m_request, true);
            return m_textData;
        }

        private string AnalysePreLoadedData(byte[] m_preLoadedData, string m_fiedName)
        {
            string str = HttpContext.Current.Request.ContentEncoding.GetString(m_preLoadedData);
            if (str.Length > 0)
            {
                string str2 = "name=\"" + m_fiedName + "\"\r\n\r\n";
                int startIndex = str.IndexOf(str2) + str2.Length;
                int index = str.IndexOf("\r\n--", startIndex);
                return str.Substring(startIndex, index - startIndex);
            }
            return string.Empty;
        }

        private void ClearApplication(HttpApplication m_application)
        {
            if (m_application.Context.Items["Webb_Upload_Stream"] != null)
            {
                FileStream stream = (FileStream) m_application.Context.Items["Webb_Upload_Stream"];
                stream.Close();
                stream = null;
            }
            if (m_application.Context.Items["Webb_Upload_GUID"] != null)
            {
                string str = (string) m_application.Context.Items["Web_Upload_UploadGUID"];
                m_application.Application.Remove("Upload_Status_" + str);
            }
        }

        public void Dispose()
        {
        }

        private long GetUpLoadFileLength()
        {
            int num = 0;
            XmlDocument document = new XmlDocument();
            document.Load(Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, "web.config"));
            XmlNode node = document.SelectSingleNode("configuration/system.web/httpRuntime/@maxRequestLength");
            if (node != null)
            {
                num = Convert.ToInt32(node.Value);
            }
            else
            {
                num = 0x400;
            }
            document = null;
            return (long) (num * 0x400);
        }

        private HttpWorkerRequest GetWorkerRequest()
        {
            return (HttpWorkerRequest) ((IServiceProvider) HttpContext.Current).GetService(typeof(HttpWorkerRequest));
        }

        public void Init(HttpApplication m_application)
        {
            m_application.BeginRequest += new EventHandler(this.WebbUpload_BeginRequest);
            m_application.EndRequest += new EventHandler(this.WebbUpload_EndRequest);
            m_application.Error += new EventHandler(this.WebbUpload_Error);
        }

        private void ReleaseResource(HttpApplication application)
        {
            if (application.Context.Items["Webb_Upload_Stream"] != null)
            {
                FileStream stream = (FileStream) application.Context.Items["Webb_Upload_Stream"];
                stream.Close();
                stream = null;
            }
            if (application.Context.Items["Webb_Upload_FileList"] != null)
            {
                Hashtable hashtable = (Hashtable) application.Context.Items["Webb_Upload_FileList"];
                foreach (object obj2 in hashtable.Values)
                {
                    if (File.Exists(obj2.ToString()))
                    {
                        File.Delete(obj2.ToString());
                    }
                }
            }
            application.Context.Items.Clear();
        }

        private void WebbUpload_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication application = sender as HttpApplication;
            HttpWorkerRequest workerRequest = this.GetWorkerRequest();
            try
            {
                string str = application.Request.ContentType.ToLower();
                if (str.StartsWith("multipart/form-data") && workerRequest.HasEntityBody())
                {
                    DateTime.Now.Subtract(this.m_beginTime);
                    int num = 0;
                    string s = "\r\n--" + str.Substring(str.IndexOf("boundary=") + 9);
                    byte[] bytes = Encoding.ASCII.GetBytes(s);
                    long num2 = Convert.ToInt64(workerRequest.GetKnownRequestHeader(11));
                    long upLoadFileLength = this.GetUpLoadFileLength();
                    if (num2 <= upLoadFileLength)
                    {
                        byte[] preloadedEntityBody = workerRequest.GetPreloadedEntityBody();
                        num += preloadedEntityBody.Length;
                        string str3 = this.AnalysePreLoadedData(preloadedEntityBody, "Webb_Upload_GUID");
                        string path = this.AnalysePreLoadedData(preloadedEntityBody, "Webb_Upload_TempPath");
                        UploadStatus status = new UploadStatus();
                        WebbRequestStream stream = new WebbRequestStream();
                        if (str3 != string.Empty)
                        {
                            status.GetUploadStatus(str3);
                        }
                        else
                        {
                            str3 = application.Application["Webb_Upload_GUID"].ToString();
                            status.GetUploadStatus(str3);
                        }
                        if (status.IsActive)
                        {
                            status.ResetBeginTime();
                            status.FileName = stream.m_rawFileName;
                            status.AllDataLength = num2;
                            status.ReadData = preloadedEntityBody.Length;
                            status.Status = UploadStatus.UploadState.Uploading;
                            HttpContext.Current.Application["Upload_Status_" + status.UploadGUID] = status;
                        }
                        if ((path != null) && Directory.Exists(path))
                        {
                            stream.SetTempPath(path);
                        }
                        stream.SetBoundaryFlag(bytes);
                        stream.SetHttpContent(WebbHelper.GetContext());
                        stream.TransactReadData(preloadedEntityBody);
                        if (!workerRequest.IsEntireEntityBodyIsPreloaded())
                        {
                            int size = 0x9fff6;
                            int num5 = 0;
                            byte[] buffer = new byte[size];
                            while ((num2 - num) > size)
                            {
                                if (!application.Context.Response.IsClientConnected)
                                {
                                    this.ReleaseResource(application);
                                    this.ClearApplication(application);
                                    break;
                                }
                                num5 = workerRequest.ReadEntityBody(buffer, size);
                                num += num5;
                                if (status.IsActive)
                                {
                                    status.GetUploadStatus(str3);
                                    status.FileName = stream.m_rawFileName;
                                    status.ReadData = num;
                                    status.Status = UploadStatus.UploadState.Uploading;
                                    HttpContext.Current.Application["Upload_Status_" + str3] = status;
                                }
                                if (stream != null)
                                {
                                    stream.TransactReadData(buffer);
                                }
                            }
                            int num6 = ((int) num2) - num;
                            byte[] buffer4 = new byte[num6];
                            if (!application.Context.Response.IsClientConnected)
                            {
                                this.ReleaseResource(application);
                                this.ClearApplication(application);
                                return;
                            }
                            num5 = workerRequest.ReadEntityBody(buffer4, num6);
                            num += num5;
                            if (status.IsActive)
                            {
                                status.GetUploadStatus(str3);
                                status.ReadData = num;
                                status.Status = UploadStatus.UploadState.Uploaded;
                                HttpContext.Current.Application["Upload_Status_" + str3] = status;
                            }
                            if (stream != null)
                            {
                                stream.TransactReadData(buffer4);
                            }
                        }
                        byte[] array = new byte[stream.ContentTextBody.Count];
                        stream.ContentTextBody.CopyTo(array);
                        stream.Dispose();
                        this.AddTextPartToRequest(workerRequest, array);
                    }
                }
            }
            catch (Exception exception)
            {
                this.ReleaseResource(application);
                this.ClearApplication(application);
                throw exception;
            }
        }

        private void WebbUpload_EndRequest(object sender, EventArgs e)
        {
        }

        private void WebbUpload_Error(object sender, EventArgs e)
        {
            this.ReleaseResource(sender as HttpApplication);
            this.ClearApplication(sender as HttpApplication);
            this.Dispose();
        }
    }
}

